
#include <BRender>
#include <BKeyEvent>
#include <BMouseEvent>
#include <BRoundHandler>

#include <BCamera>
#include <BViewer>
#include <BShape>
#include <BMaterial>
#include <BOpenGL>
#include <BSystem>
#include <BMesh>
#include <BSphere>

#include "../operas/RemoveOpera.h"
#include "VertexTransformer.h"

VertexTransformer::VertexTransformer()
{
	_target = 0;
	_leftPressed = false;
	_dirty = false;

	connect(this, Signal_AssetChanged, &VertexTransformer::slotAssetChanged);
}
VertexTransformer::~VertexTransformer()
{

}

void VertexTransformer::setPrimitive(Primitive primitive)
{
	_primitive = primitive;
	_dirty = true;
	this->fresh();
}
Primitive VertexTransformer::primitive() const
{
	return _primitive;
}

void VertexTransformer::setIndexSet(const BIntSet& indexSet)
{
	_indexSet = indexSet;
	if (_indexSet.size())
	{
		BSpace space(_vertices->at(_indexSet.first()));
		for (int i = 0; i < _indexSet.size(); i++)
		{
			int index = _indexSet[i];
			space.expand(_vertices->at(index));
		}
		_pointsBox = space;
	}
	this->setOrigin(_pointsBox.center());
	this->setMatrix(_pointsBox.center());
	this->fresh();
}
const BIntSet& VertexTransformer::indexSet() const
{
	return _indexSet;
}

void VertexTransformer::startTransform(const BMatrix& matrix)
{
	if (_shape)
	{
		_originCenter = _pointsBox.center();
		_transOpera = new VertexTransOpera(_shape, _vertices, _indexSet);
	}
}
void VertexTransformer::transforming(const BMatrix& matrix)
{
	if (_target && _transOpera)
	{
		BMatrix origin = this->origin().inverse();
		BMatrix newMatrix = matrix * origin;
		_transOpera->freshNewPoints(newMatrix);
		_transOpera->redo();
		this->fresh();
	}
}
void VertexTransformer::finishTransform(const BMatrix& matrix)
{
	if (_target && _transOpera)
	{
		emit("opera", _transOpera);
		emit(Signal_Finished, _indexSet);
		_transOpera = 0;
		this->fresh();
	}
}

void VertexTransformer::slotAssetChanged(BObject* object, const BValue& value)
{
	Target* target = value;
	if (_target != target)
	{
		if (_target)
		{
			_shape = 0;
			_vertices = 0;
			_indexSet.clear();
			disconnect(_target);
		}
		_target = target;
		if (_target)
		{
			_shape = _target->shape();
			connect(_target, Signal_Dirty, &VertexTransformer::slotTragetDirty);
			if (BPickHit* hit = _target->pickHit(0))
			{
				setBasicMatrix(hit->absoluteMatrix());
			}
		}
	}
	_dirty = true;
	this->fresh();
}
void VertexTransformer::slotTragetDirty(BObject* object, const BValue& value)
{
	if (_transOpera.empty())
	{

	}
}

void VertexTransformer::render(BRender& render)
{
	TransformHandler::render(render);
	render.pushMatrix(this->basicMatrix());
	render.setDepthTest(false);
	render.setColor(200, 200, 100, 200);
	render.drawBox(_pointsBox);
	render.popMatrix();
}

void VertexTransformer::freshEvent(const BEvent& event)
{
	TransformHandler::freshEvent(event);
}
